﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UFPE.CIn.Abc.Primality.Util;
using UFPE.CIn.Abc.Primality.Algorithms;

namespace FerramentaComparacao
{
    public partial class TelaPrincipal : Form
    {
        private BigInteger validNumber;
        private Testes testes;
        private static readonly BigInteger empty = new BigInteger();
        private List<CheckBox> algorithms;

        public TelaPrincipal()
        {
            InitializeComponent();
            validNumber = empty;

            algorithms = new List<CheckBox>();
            testes = Testes.Instance;
            CarregarListaAlgoritmos();
        }

        private void CarregarListaAlgoritmos()
        {
            List<string> testNames = testes.GetAlgorithmNames();

            int pos = 0;

            foreach (string item in testNames)
            {
                CheckBox ckb = new CheckBox();
                ckb.Text = item;
                ckb.Location = new Point(20, pos += 20);
                ckb.Size = new Size(200, 20);

                algorithms.Add(ckb);
                grpAlgorithms.Controls.Add(ckb);
            }
        }

        private void txtNumero_TextChanged(object sender, EventArgs e)
        {
            try
            {
                validNumber = new BigInteger(txtNumero.Text, 10);
            }
            catch
            {
                if (String.IsNullOrEmpty(txtNumero.Text))
                {
                    validNumber = empty;
                }
                else
                {
                    MessageBox.Show("Número inválido!");
                    txtNumero.Text = (validNumber == 0? "" : validNumber.ToString());
                    txtNumero.SelectionStart = txtNumero.Text.Length;
                }
            }
        }

        private void btnComecar_Click(object sender, EventArgs e)
        {
            Dictionary<string, Pair<bool, long>> algoritmoXtempo = new Dictionary<string, Pair<bool, long>>();
            bool algumMarcado = false;

            foreach (CheckBox item in algorithms)
            {
                bool resultado;

                if (item.Checked)
                {
                    algumMarcado = true;
                    try
                    {
                        long threshold = testes.GetThreshold(item.Text);
                        if (threshold > 0 && validNumber >= threshold)
                        {
                            DialogResult escolha = MessageBox.Show("O método " + item.Text + " pode ser muito demorado para o número a ser testado. \n\nDeseja realmente usar este teste?", "CUIDADO!", MessageBoxButtons.YesNo);

                            if (escolha == DialogResult.No)
                            {
                                continue;
                            }
                        }

                        resultado = testes.CallAlgorithm(item.Text, validNumber);

                        //MessageBox.Show(String.Format("{0} é primo? {1} diz que {2} em {3}ms", validNumber, item.Text, resultado == true ? "sim" : "não", testes.TimeLastRun(item.Text)), item.Text);

                        algoritmoXtempo.Add(item.Text, new Pair<bool, long>(resultado, testes.TimeLastRun(item.Text)));
                    }
                    catch (KeyNotFoundException)
                    {
                        System.Windows.Forms.MessageBox.Show("Algoritmo inexistente");
                    }
                    catch
                    {
                        System.Windows.Forms.MessageBox.Show("Ooops... Um erro aconteceu. Tente novamente!");
                    }
                }
            }

            if (algumMarcado)
            {
                //DialogResult relatorio = MessageBox.Show("Deseja visualizar o relatório final dos tempos de execução?", "Atenção:", MessageBoxButtons.YesNo);

                //if (relatorio == DialogResult.Yes)
                //{
                    //StringBuilder sb = new StringBuilder();

                    //sb.AppendLine("Relatório de execução dos algoritmos:");
                    //sb.AppendLine();

                    //foreach (var item in algoritmoXtempo)
                    //{
                    //    sb.Append(item.Key);
                    //    for (int i = item.Key.Length; i <= 60; i++)
                    //    {
                    //        sb.Append(" ");
                    //    }

                    //    sb.Append(item.Value.Second);
                    //    sb.Append("ms (");
                    //    sb.Append(item.Value.First ? "SIM" : "NÃO");
                    //    sb.AppendLine(")");
                    //}

                    //MessageBox.Show(sb.ToString(), "Relatório");

                    Resultado resultado = new Resultado(algoritmoXtempo);
                    resultado.ShowDialog();
                //}
            }
        }
    }
}
